package com.jinlia.show.modules.base.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinlia.show.common.core.utils.PageUtils;
import com.jinlia.show.modules.base.model.form.RoleForm;
import com.jinlia.show.modules.base.model.po.SysRolePO;
import com.jinlia.show.modules.base.model.query.RolePageQuery;
import com.jinlia.show.modules.base.system.entity.SysRole;
import com.jinlia.show.modules.base.system.entity.SysRoleMenu;
import com.jinlia.show.modules.base.system.entity.SysUserRole;
import com.jinlia.show.modules.base.system.mapper.SysRoleMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysRoleMapperService extends ServiceImpl<SysRoleMapper, SysRole> {


    @Autowired
    SysRoleMenuMapperService sysRoleMenuMapperService;
    @Autowired
    SysUserRoleMapperService sysUserRoleMapperService;

    /**
     * 通过用户id
     *
     * @param userId
     * @return
     */
    public List<SysRole> getRolesByUserId(Long userId) {
        List<SysRole> byUserId = this.baseMapper.getByUserId(userId);
        return byUserId;
    }

    public IPage<SysRolePO> getRolePage(RolePageQuery queryParams) {
        // 构建分页参数
        Page<SysRole> page = new Page<>(queryParams.getCurrent(), queryParams.getSize());
        //构造查询参数
        LambdaQueryWrapper<SysRole> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.like(StringUtils.hasLength(queryParams.getKeywords()), SysRole::getName, queryParams.getKeywords());
        Page<SysRole> pageSysUser = this.page(page, lambdaQueryWrapper);
        Page<SysRolePO> sysUserVOPage = PageUtils.tToVO(pageSysUser, SysRolePO.class);
        //todo
        if (!CollectionUtils.isEmpty(sysUserVOPage.getRecords())) {
            List<SysRoleMenu> listSysRoleMenu = sysRoleMenuMapperService.lambdaQuery()
                    .in(SysRoleMenu::getRoleId, sysUserVOPage.getRecords().stream().map(SysRolePO::getId).collect(Collectors.toList()))
                    .list();
            Map<Long, List<SysRoleMenu>> collect = listSysRoleMenu.stream().collect(Collectors.groupingBy(SysRoleMenu::getRoleId));
            for (SysRolePO record : sysUserVOPage.getRecords()) {
                if (collect.containsKey(record.getId())) {
                    record.setMenuIds(collect.get(record.getId()).stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet()));
                }
            }

        }
        return sysUserVOPage;
    }

    public void addSysRole(RoleForm sysRole) {
        if (sysRole.getId() == null) {
            this.save(sysRole);
        }else {
            this.updateById(sysRole);
        }

        tranceVO(sysRole);
    }

    public void updateSysRole(RoleForm sysRole) {
        this.updateById(sysRole);
        sysRoleMenuMapperService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, sysRole.getId()));
        tranceVO(sysRole);
    }

    private void tranceVO(RoleForm sysRole) {
        if (!Objects.isNull(sysRole.getMenuIds())) {
            sysRoleMenuMapperService.saveBatch(sysRole.getMenuIds().stream().map(menuId -> {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setRoleId(sysRole.getId());
                sysRoleMenu.setMenuId(menuId);
                return sysRoleMenu;
            }).collect(Collectors.toList()));
        }
    }

    public void addUser(RoleForm roleForm) {
        sysUserRoleMapperService.saveBatch(roleForm.getUserIds().stream().map(userId -> {
            SysUserRole sysRoleMenu = new SysUserRole();
            sysRoleMenu.setRoleId(roleForm.getId());
            sysRoleMenu.setUserId(userId);
            return sysRoleMenu;
        }).collect(Collectors.toList()));
    }

    public void delUser(RoleForm roleForm) {
        roleForm.getUserIds().forEach(userId -> {
            sysUserRoleMapperService.lambdaUpdate()
                    .eq(SysUserRole::getRoleId, roleForm.getId())
                    .eq(SysUserRole::getUserId, userId)
                    .remove();
        });
    }
}
